package com.mes.cloud.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mes.cloud.api.dto.request.UpdateEnableRequest;
import com.mes.cloud.api.dto.request.organization.*;
import com.mes.cloud.api.dto.response.organization.*;
import com.mes.cloud.exception.BaseException;
import com.mes.cloud.common.CommPager;
import com.mes.cloud.common.JsonResult;
import com.mes.cloud.constant.Constants;
import com.mes.cloud.dao.BaseChannelDao;
import com.mes.cloud.dao.SysOrganizationDao;
import com.mes.cloud.entity.SysOrganization;
import com.mes.cloud.entity.SysOrganizationArea;
import com.mes.cloud.entity.SysOrganizationLog;
import com.mes.cloud.entity.vo.organization.SysOrganizationDetailsVo;
import com.mes.cloud.enums.HttpStatusEnum;
import com.mes.cloud.util.DateUtil;
import com.mes.cloud.util.UserUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 组织表
 *
 * @author xy
 * @version 2019-07-30 09:35:59
 * @email yuan.xue3@pactera.com
 */
@SuppressWarnings("JavaDoc")
@Service
public class SysOrganizationService {

    private SysOrganizationDao sysOrganizationDao;
    private BaseChannelDao baseChannelDao;
    private IPKeyGenerator ipKeyGenerator;
    private SysOrganizationAreaService sysOrganizationAreaService;
    private LogService logService;
    private SysCodeGeneratorService sysCodeGeneratorService;

    @SuppressWarnings("SpringJavaAutowiringInspection")
    @Autowired
    public SysOrganizationService(SysOrganizationDao sysOrganizationDao, IPKeyGenerator ipKeyGenerator
            , SysOrganizationAreaService sysOrganizationAreaService, BaseChannelDao baseChannelDao
            , LogService logService
            , SysCodeGeneratorService sysCodeGeneratorService
    ) {
        this.sysOrganizationDao = sysOrganizationDao;
        this.baseChannelDao = baseChannelDao;
        this.ipKeyGenerator = ipKeyGenerator;
        this.sysOrganizationAreaService = sysOrganizationAreaService;
        this.logService = logService;
        this.sysCodeGeneratorService = sysCodeGeneratorService;

    }

    /**
     * <分页查询>
     *
     * @param pageRequest
     * @return com.shinho.tntframe.core.common.model.CommPager<com.shinho.crm.base.api.dto.response.organization.SysOrganizationDto>
     * @author xy
     * @date 2019/8/8 18:03
     */
    public CommPager<SysOrganizationDto> selectPage(SysOrganizationPageRequest pageRequest) {//xue
        Page<SysOrganizationDto> page = PageHelper.startPage(pageRequest.getCurrentPage(), pageRequest.getPageSize());
        //查询条件
        String employeeId = UserUtil.getEmployeeId();
        pageRequest.setDelFlag(Constants.DEL_FLAG_NO);
        pageRequest.setEmployeeId(employeeId);
        List<SysOrganization> sysOrganizationList = sysOrganizationDao.selectPage(pageRequest);

        List<SysOrganizationDto> sysOrganizationDtoList = new ArrayList<>();
        for (SysOrganization sysOrganization : sysOrganizationList) {
            SysOrganizationDto sysOrganizationDto = new SysOrganizationDto();
            BeanUtils.copyProperties(sysOrganization, sysOrganizationDto);
            sysOrganizationDtoList.add(sysOrganizationDto);
        }

        return new CommPager<>(page, sysOrganizationDtoList);
    }

    /**
     * <查询列表>
     *
     * @param sysOrganizationPositionAuthRequest
     * @return java.util.List<com.shinho.crm.base.api.dto.response.organization.SysOrganizationDto>
     * @author xy
     * @date 2019/8/8 18:04
     */
    public List<SysOrganizationTreeDto> list(SysOrganizationPositionAuthRequest sysOrganizationPositionAuthRequest) {
        //查询有效组织
        List<SysOrganization> sysOrganizationList = sysOrganizationDao.listAll();
        List<SysOrganizationTreeDto> sysOrganizationDtoList = new ArrayList<>();
        for (SysOrganization sysOrganization : sysOrganizationList) {
            SysOrganizationTreeDto sysOrganizationTreeDto = new SysOrganizationTreeDto();
            BeanUtils.copyProperties(sysOrganization, sysOrganizationTreeDto);
            sysOrganizationDtoList.add(sysOrganizationTreeDto);
        }

        //岗位组织授权关联组织 查询岗位下的所以组织
        List<SysOrganization> sysPositionOrgAuthList = sysOrganizationDao.listRelationPositionOrgAuth(sysOrganizationPositionAuthRequest.getPositionId());
        List<SysOrganizationTreeDto> sysPositionOrgAuthDtoList = new ArrayList<>();
        for (SysOrganization sysOrganization : sysPositionOrgAuthList) {
            SysOrganizationTreeDto sysOrganizationTreeDto = new SysOrganizationTreeDto();
            BeanUtils.copyProperties(sysOrganization, sysOrganizationTreeDto);
            sysPositionOrgAuthDtoList.add(sysOrganizationTreeDto);
        }
        //数据合并
        List<SysOrganizationTreeDto> listAll = new ArrayList<>();
        listAll.addAll(sysOrganizationDtoList);
        listAll.addAll(sysPositionOrgAuthDtoList);

        return listAll;
    }

    /**
     * <新增>
     *
     * @param sysOrganizationRequest
     * @return com.shinho.tntframe.core.common.model.JsonResult
     * @author xy
     * @date 2019/8/5 9:10
     */
    @SuppressWarnings("unchecked")
    @Transactional(rollbackFor = Exception.class)
    public JsonResult<SysOrganizationDto> insertSelective(SysOrganizationRequest sysOrganizationRequest) {
        JsonResult jsonResult = new JsonResult();
        SysOrganization sysOrganization = new SysOrganization();
        BeanUtils.copyProperties(sysOrganizationRequest, sysOrganization);
        //设置Code
        String code = sysCodeGeneratorService.getCode(Constants.CODE_GENERATOR_ORGANIZATION);
        sysOrganization.setCode(Constants.CODE_ORGANIZATION_PREFIX + code);
        //设置父级组
        String parentGroup = sysOrganizationDao.getParentGroupById(sysOrganization.getParentId());
        if (StringUtils.isEmpty(parentGroup)) {
            //如果未查询到父集组设0
            sysOrganization.setParentGroup("0");
        } else {
            sysOrganization.setParentGroup("0,"+parentGroup);
        }

        String id = ipKeyGenerator.getGenerateKey();
        sysOrganization.setId(id);
        sysOrganization.setUpdateDateStr(DateUtil.updateDateStr());
        sysOrganization.setCreateBy(UserUtil.getCreateByName());
        sysOrganization.setUpdateBy(UserUtil.getUpdateByName());
        sysOrganization.setCreateByNo(UserUtil.getCreateByNo());
        sysOrganization.setUpdateByNo(UserUtil.getUpdateByNo());
        //插入行政区划
        int count = sysOrganizationDao.insertSelective(sysOrganization);
        if (count > 0) {
            this.insetArea(id, sysOrganizationRequest.getAreaIds());
            this.insertLog(sysOrganization.getId(), Constants.ADD_ORGANIZATION);
            jsonResult.setMsg(HttpStatusEnum.OK.getMessage());
            jsonResult.setCode(HttpStatusEnum.OK.getCode());
            SysOrganizationDto sysOrganizationDto = new SysOrganizationDto();
            BeanUtils.copyProperties(sysOrganization, sysOrganizationDto);
            jsonResult.setData(sysOrganizationDto);
        } else {
            throw new BaseException(HttpStatusEnum.FAIL.getCode(),HttpStatusEnum.FAIL.getMessage());
        }
        return jsonResult;
    }

    /**
     * <增加组织行政区划>
     *
     * @param id,areaIds
     * @return int
     * @author xy
     * @date 2019/8/1 15:56
     */
    @SuppressWarnings("ConstantConditions")
    private void insetArea(String id, String areaIds) {
        //行政区划ids
        if (StringUtils.isNotBlank(areaIds)) {
            String[] areaIdArray = areaIds.split(",");
            List<SysOrganizationArea> sysOrganizationAreas = new ArrayList<>(56);

            if (Objects.nonNull(areaIdArray)) {
                for (int i = 0; i < areaIdArray.length; i++) {
                    SysOrganizationArea sysOrganizationArea = new SysOrganizationArea();
                    sysOrganizationArea.setId(ipKeyGenerator.getGenerateKey());
                    sysOrganizationArea.setOrganizationId(id);
                    sysOrganizationArea.setAreaId(areaIdArray[i]);
                    sysOrganizationArea.setUpdateDateStr(DateUtil.updateDateStr());
                    sysOrganizationArea.setCreateBy(UserUtil.getCreateByName());
                    sysOrganizationArea.setUpdateBy(UserUtil.getUpdateByName());
                    sysOrganizationArea.setCreateByNo(UserUtil.getCreateByNo());
                    sysOrganizationArea.setUpdateByNo(UserUtil.getUpdateByNo());
                    sysOrganizationAreas.add(sysOrganizationArea);
                }
            }
            if (!CollectionUtils.isEmpty(sysOrganizationAreas) && sysOrganizationAreas.size() > 0) {
                sysOrganizationAreaService.batchInsert(sysOrganizationAreas);
            }
        }
    }

    /**
     * <更新>
     *
     * @param sysOrganizationRequest
     * @return com.shinho.tntframe.core.common.model.JsonResult
     * @author xy
     * @date 2019/8/5 9:11
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult updateSelectiveById(SysOrganizationRequest sysOrganizationRequest) {
       String parentId = sysOrganizationRequest.getParentId();
        //更新行政区划
        updateArea(sysOrganizationRequest.getId(), sysOrganizationRequest.getAreaIds());

        SysOrganization sysOrganization = new SysOrganization();
        BeanUtils.copyProperties(sysOrganizationRequest, sysOrganization);
        sysOrganization.setUpdateDateStr(DateUtil.updateDateStr());
        sysOrganization.setUpdateBy(UserUtil.getUpdateByName());
        sysOrganization.setUpdateByNo(UserUtil.getUpdateByNo());

        //设置父集组
        String parentGroup = sysOrganizationDao.getParentGroupById(sysOrganization.getParentId());
        if (StringUtils.isEmpty(parentGroup)) {
            //如果未查询到父集组设0
            sysOrganization.setParentGroup("0");
        } else {
            sysOrganization.setParentGroup("0,"+parentGroup);
        }

        //查询未修改前记录
        SysOrganization queryParams = new SysOrganization();
        queryParams.setId(sysOrganizationRequest.getId());
        SysOrganization historySysOrganization = sysOrganizationDao.selectByPrimaryKey(queryParams);

        //更新提交修改
        int count = sysOrganizationDao.updateByPrimaryKeySelective(sysOrganization);

        //更新子节点父级组
        updateOrgChildrenParentGroup(historySysOrganization.getId(), historySysOrganization.getParentId(), parentId);

        JsonResult jsonResult = new JsonResult();
        if (count > 0) {
            this.insertLog(sysOrganization.getId(), Constants.UPDATE_ORGANIZATION);
            jsonResult.setMsg(HttpStatusEnum.OK.getMessage());
            jsonResult.setCode(HttpStatusEnum.OK.getCode());
        } else {
            throw new BaseException(HttpStatusEnum.FAIL.getCode(),HttpStatusEnum.FAIL.getMessage());
        }
        return jsonResult;
    }

    /**
     * 更新组织子节点 父级组
     *
     * @param orgId
     * @param historyOrgParentId
     * @param parentId
     */
    private void updateOrgChildrenParentGroup(String orgId, String historyOrgParentId, String parentId) {

        //如果上级节点发生变化
        if (!historyOrgParentId.equals(parentId)) {
            //找出当前节点的所有子节点 用于更新子节点父级组
            List<SysOrganization> list = sysOrganizationDao.selectChildrens(orgId);
            //遍历
            for (SysOrganization org : list) {

                SysOrganization updateOrganization = new SysOrganization();
                //查询当前节点的新父级组
                String parentGroupId = sysOrganizationDao.getParentGroupById(org.getParentId());
                if (StringUtils.isEmpty(parentGroupId)) {
                    //如果未查询到父集组设0
                    updateOrganization.setParentGroup("0");
                } else {
                    updateOrganization.setParentGroup(parentGroupId);
                }
                updateOrganization.setId(org.getId());
                updateOrganization.setUpdateDateStr(DateUtil.updateDateStr());
                updateOrganization.setUpdateBy(UserUtil.getUpdateByName());
                updateOrganization.setUpdateByNo(UserUtil.getUpdateByNo());
                sysOrganizationDao.updateByPrimaryKeySelective(updateOrganization);
            }

        }

    }

    /**
     * <更新行政区划>
     *
     * @param orgId,areaIds
     * @return int
     * @author xy
     * @date 2019/8/1 16:45
     */
    private void updateArea(String orgId, String areaIds) {

        SysOrganizationAreaRequest sysOrganizationAreaRequest = new SysOrganizationAreaRequest();
        sysOrganizationAreaRequest.setOrganizationId(orgId);
        sysOrganizationAreaRequest.setDelFlag(Constants.DEL_FLAG_NO);
        List<SysOrganizationAreaDto> sysOrganizations = sysOrganizationAreaService.listByOrganizationId(sysOrganizationAreaRequest);
        //如果组织下存在未删除的数据,则把数据更新为删除状态
        if (!CollectionUtils.isEmpty(sysOrganizations)) {
            SysOrganizationArea sysOrganizationArea = new SysOrganizationArea();
            sysOrganizationArea.setOrganizationId(orgId);
            sysOrganizationArea.setDelFlag(Constants.DEL_FLAG_YES);
            sysOrganizationArea.setUpdateDateStr(DateUtil.updateDateStr());
            sysOrganizationArea.setUpdateBy(UserUtil.getUpdateByName());
            sysOrganizationArea.setUpdateByNo(UserUtil.getUpdateByNo());
            sysOrganizationAreaService.updateByOrganizationId(sysOrganizationArea);
        }
        this.insetArea(orgId, areaIds);
    }

    /**
     * <查询组织详细信息>
     *
     * @param id
     * @return SysOrganizationDetailsDto
     * @author xy
     * @date 2019/8/2 19:11
     */
    public SysOrganizationDetailsDto get(String id) {
        SysOrganizationDetailsVo sysOrganizationDetailVo = sysOrganizationDao.getSysOrganizationDetail(id);
        SysOrganizationDetailsDto sysOrganizationDto = new SysOrganizationDetailsDto();

        if(!Objects.isNull(sysOrganizationDetailVo)){
            BeanUtils.copyProperties(sysOrganizationDetailVo, sysOrganizationDto);
            //查询组织行政区划
            SysOrganizationAreaRequest sysOrganizationAreaRequest = new SysOrganizationAreaRequest();
            sysOrganizationAreaRequest.setOrganizationId(id);
            sysOrganizationAreaRequest.setDelFlag(Constants.DEL_FLAG_NO);
            List<SysOrganizationAreaDto> sysOrganizationAreas = sysOrganizationAreaService.listByOrganizationId(sysOrganizationAreaRequest);
            sysOrganizationDto.setSysOrganizationAreas(sysOrganizationAreas);
        }
        return sysOrganizationDto;
    }

    /**
     * <禁用启用>
     *
     * @param updateEnableRequest
     * @return JsonResult
     * @author xy
     * @date 2019/8/2 15:45
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult updateEnableFlag(UpdateEnableRequest updateEnableRequest) {
        String orgId = updateEnableRequest.getIds().get(0);
        String enable = updateEnableRequest.getEnableFlag();
        String flag = Constants.ENABLE_ORGANIZATION;

        JsonResult jsonResult = new JsonResult();
        //如果当前操作是禁用
        if (Constants.ENABLE_FLAG_NO.equals(enable)) {
            flag = Constants.DISABLE_ORGANIZATION;
            SysOrganization sysOrganization = new SysOrganization();
            sysOrganization.setParentId(orgId);
            sysOrganization.setEnableFlag(Constants.ENABLE_FLAG_YES);
            int sysOrganizationSize = sysOrganizationDao.selectCount(sysOrganization);
            //检查组织是否子节点，如果有不能被禁用
            if (sysOrganizationSize > 0) {
                jsonResult.setMsg(HttpStatusEnum.ORG_CHILDREN_EXIST.getMessage());
                jsonResult.setCode(HttpStatusEnum.ORG_CHILDREN_EXIST.getCode());
                return jsonResult;
            }
        }

        updateEnableRequest.setUpdateDateStr(DateUtil.updateDateStr());
        updateEnableRequest.setUpdateBy(UserUtil.getUpdateByName());
        updateEnableRequest.setUpdateByNo(UserUtil.getUpdateByNo());

        int count = sysOrganizationDao.batchUpdateEnable(updateEnableRequest);
        if (count > 0) {
            // 插入操作日志
            for (String id : updateEnableRequest.getIds()) {
                this.insertLog(id, flag);
            }
            jsonResult.setMsg(HttpStatusEnum.OK.getMessage());
            jsonResult.setCode(HttpStatusEnum.OK.getCode());
        } else {
            throw new BaseException(HttpStatusEnum.FAIL.getCode(),HttpStatusEnum.FAIL.getMessage());
        }

        return jsonResult;
    }

    /**
     * <组织树查询>
     *
     * @return List<SysOrganizationDto>
     * @author xy
     * @date 2019/8/2 15:43
     */
    public List<SysOrganizationTreeAuthDto> treeList() {

        String employeeId = UserUtil.getEmployeeId();

        List<SysOrganization> sysOrganizationList = sysOrganizationDao.selectAuthOrgByEmployeeId(employeeId);

        List<SysOrganizationTreeAuthDto> sysOrganizationTreeAuthDtoList = new ArrayList<>();
        for (SysOrganization sysOrganization : sysOrganizationList) {
            SysOrganizationTreeAuthDto sysOrganizationTreeAuthDto = new SysOrganizationTreeAuthDto();
            BeanUtils.copyProperties(sysOrganization, sysOrganizationTreeAuthDto);
            sysOrganizationTreeAuthDtoList.add(sysOrganizationTreeAuthDto);
        }

        return sysOrganizationTreeAuthDtoList;
    }

    /**
     * <插入日志>
     *
     * @param id, logMessage
     * @author xy
     * @date 2019/8/8 19:25
     */
    private void insertLog(String id, String logMessage) {
        SysOrganizationLog sysOrganizationLog = new SysOrganizationLog();
        sysOrganizationLog.setOrganizationId(id);
        sysOrganizationLog.setMenuCode(Constants.ORGANIZATION_MENU_CODE);
        sysOrganizationLog.setLog(logMessage);
        sysOrganizationLog.setId(ipKeyGenerator.getGenerateKey());
        sysOrganizationLog.setUpdateDateStr(DateUtil.updateDateStr());
        sysOrganizationLog.setCreateBy(UserUtil.getCreateByName());
        sysOrganizationLog.setUpdateBy(UserUtil.getUpdateByName());
        sysOrganizationLog.setCreateByNo(UserUtil.getCreateByNo());
        sysOrganizationLog.setUpdateByNo(UserUtil.getUpdateByNo());
        logService.insertOrganizationLog(sysOrganizationLog);
    }

    /**
     * 获取组织下所有组织
     * 获取子节点
     *
     * @param synchroOrganizationFindSubByIdRequest
     * @return
     */
    public JsonResult<List<SysOrganizationDto>> synchroFindSubById(SynchroOrganizationFindSubByIdRequest synchroOrganizationFindSubByIdRequest) {
        JsonResult<List<SysOrganizationDto>> jsonResult = new JsonResult<>();
        List<SysOrganization> sysOrganizationList = sysOrganizationDao.findSubById(synchroOrganizationFindSubByIdRequest);
        List<SysOrganizationDto> sysOrganizationDtoList = new ArrayList<>();
        for (SysOrganization sysOrganization : sysOrganizationList) {
            SysOrganizationDto sysOrganizationDto = new SysOrganizationDto();
            BeanUtils.copyProperties(sysOrganization, sysOrganizationDto);
            sysOrganizationDtoList.add(sysOrganizationDto);
        }
        jsonResult.setMsg(HttpStatusEnum.OK.getMessage());
        jsonResult.setCode(HttpStatusEnum.OK.getCode());
        return jsonResult.setData(sysOrganizationDtoList);
    }

    /**
     * <编辑组织时查询员工授权组织并且排除当前组织的自身与下级>
     *
     * @return List<SysOrganizationDto>
     * @author xy
     * @date 2019/8/2 15:43
     */
    public JsonResult<List<SysOrganizationDto>> excludeQueryAuthOrganization(SysOrganizationUpdateRequest request) {
        JsonResult<List<SysOrganizationDto>> jsonResult = new JsonResult<>();
        //当前登录者
        String employeeId = UserUtil.getEmployeeId();
        request.setEmployeeId(employeeId);

        //查询当前节点的所有子节点
        List<SysOrganization> childrenList = sysOrganizationDao.selectChildrens(request.getOrganizationId());
        //noinspection SpellCheckingInspection
        List<String> childrenIds = new ArrayList<>();
        //排除自身条件
        childrenIds.add(request.getOrganizationId());
        for (SysOrganization sysOrganization : childrenList) {
            childrenIds.add(sysOrganization.getId());
        }
        request.setOrganizationIds(childrenIds);
        List<SysOrganization> sysOrganizationList = sysOrganizationDao.excludeQueryAuthOrganization(request);

        List<SysOrganizationDto> sysOrganizationDtoList = new ArrayList<>();
        for (SysOrganization sysOrganization : sysOrganizationList) {
            SysOrganizationDto sysOrganizationDto = new SysOrganizationDto();
            BeanUtils.copyProperties(sysOrganization, sysOrganizationDto);
            sysOrganizationDtoList.add(sysOrganizationDto);
        }
        jsonResult.setMsg(HttpStatusEnum.OK.getMessage());
        jsonResult.setCode(HttpStatusEnum.OK.getCode());
        jsonResult.setData(sysOrganizationDtoList);
        return jsonResult;
    }

    /**
     * <组织树查询>
     *
     * @return List<SysOrganizationDto>
     * @author xy
     * @date 2019/8/2 15:43
     */
    public  JsonResult<List<String>> listChildren(List<String> orgAuthIds) {
        JsonResult<List<String>> jsonResult = new JsonResult<>();
        List<String> listChildren = sysOrganizationDao.listChildren(orgAuthIds);
        jsonResult.setMsg(HttpStatusEnum.OK.getMessage());
        jsonResult.setCode(HttpStatusEnum.OK.getCode());
        jsonResult.setData(listChildren);
        return jsonResult;
    }

    public  JsonResult<SysOrganizationDto> getOrgParent(SysOrganizationRequest sysOrganizationRequest) {
        JsonResult<SysOrganizationDto> jsonResult = new JsonResult<>();
        SysOrganization sysOrganization = sysOrganizationDao.getOrgParent(sysOrganizationRequest);
        if(!Objects.isNull(sysOrganization)){
            SysOrganizationDto sysOrganizationDto = new SysOrganizationDto();
            BeanUtils.copyProperties(sysOrganization, sysOrganizationDto);
            jsonResult.setData(sysOrganizationDto);
        }
        jsonResult.setMsg(HttpStatusEnum.OK.getMessage());
        jsonResult.setCode(HttpStatusEnum.OK.getCode());
        return jsonResult;
    }
}
